<?php

// namespace Wxcrypt\Crypt;

/**

 * 对微信获取平台证书加密数据的解密.

 *

 * @copyright Copyright (c) 1998-2014 Tencent Inc.

 */



class Aesutils

{

    // AES 自己设置的密钥

    private $aesKey             =   'junengPao_shenzhenbaojielongkeji11111';

    // private $aesKey             =   'weicanghuishihangyelongtoudageda';



    // 私钥位置
    // $keyPath = dirname($_SERVER['DOCUMENT_ROOT']).'/vendor/cert/apiclient_key.pem';
    // private $keyPath            =   '/www/wwwroot/ceshi/vendor/cert/apiclient_key.pem';
    private $path='';
    private $keyPath='';
    // private $keyPath            =   'E:/phpstudy_pro/WWW/energy-gathering-run/vendor/cert/apiclient_key.pem';
    private $apiclient_cert='';


    // 服务商商户号

    private $merchant_id        =   '16731864251111';

    // private $merchant_id        =   '1598953571';



    // 商户API证书序列号

    private $serial_no          =   '5A94E741CBF09DEAC74ECA04480384A6380E50D3';

    // private $serial_no          =   '208B6858AF818B1F7158D6B57C1A6D79E647D2A5';



    // 绑定的小程序、公众号appid

    private $appId              =   'wxf0572df6663fae1d1111';//
    private $spappId            =   'wxce075e11e90a8f4c11111';

    // private $appId              =   'wx20bf53d34226d9ab';





    const KEY_LENGTH_BYTE       =   32;

    const AUTH_TAG_LENGTH_BYTE  =   16;

 

    /**

     * Constructor

     */

    public function __construct()

    {

        $rootPath = realpath($_SERVER['DOCUMENT_ROOT']);
        
        // 获取根目录的上级目录
        $this->path = realpath($rootPath . '/..');
        $this->keyPath            =   $this->path.'/vendor/cert/apiclient_key.pem';



        // 证书位置
    
        // private $apiclient_cert     =   'E:/phpstudy_pro/WWW/energy-gathering-run/vendor/cert/apiclient_cert.pem';
    
        $this->apiclient_cert     =   $this->path.'/vendor/cert/apiclient_cert.pem';
    
    }

 

    /**

     * 获取的数据解密 AEAD_AES_256_GCM ciphertext

     *

     * @param String    $associatedData     AES GCM additional authentication data 这是get_Certificate()获取到的associated_data

     * @param String    $nonceStr           AES GCM nonce 这是get_Certificate()获取到的noce

     * @param String    $ciphertext         AES GCM cipher text 这是get_Certificate()获取到的ciphertext

     *

     * @return String|bool      Decrypted string on success or FALSE on failure

     */

    public function decryptToString($associatedData, $nonceStr, $ciphertext,$aesKey='')

    {

        if (empty($aesKey)) {

            $aesKey = $this->aesKey;

        }



        $ciphertext     =   \base64_decode($ciphertext);

        if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) {

            return false;

        }

 

        // ext-sodium (default installed on >= PHP 7.2)

        if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') &&

            \sodium_crypto_aead_aes256gcm_is_available()) {

            return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);

        }

 

        // ext-libsodium (need install libsodium-php 1.x via pecl)

        if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') &&

            \Sodium\crypto_aead_aes256gcm_is_available()) {

            return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);

        }

 

        // openssl (PHP >= 7.1 support AEAD)

        if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {

            $ctext      =   substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);

            $authTag    =   substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);

 

            return \openssl_decrypt($ctext, 'aes-256-gcm', $aesKey, \OPENSSL_RAW_DATA, $nonceStr,

                $authTag, $associatedData);

        }

 

        throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');

    }

    

    /**

     * 入驻商家，成为二级商户(小V商户)

     * 

     * @param  Array    $userinfo      订单信息

     *                  [

     *                      out_request_no      业务申请编号

     *                      contact_name        超级管理员姓名 该姓名需与法人身份证姓名一致

     *                      id_card             超级管理身份证号

     *                      mobile_phone        超级管理员手机号

     *                      id_card_copy        超级管理身份证人像面照地址

     *                      id_card_national    超级管理身份证国徽面照片地址

     *                      id_card_valid_time  超级管理身份证有效期限

     *                      store_name          店铺名称

     *                      merchant_shortname  商户简称

     *                      store_qr_code       店铺二维码图片地址

     *                  ]                

     * 

     * @return Array                    二级商户申请信息

     */

    public function er_shop_user($userinfo){

        

        $error_array        =   [

            'out_request_no'        =>  '请上传业务申请编号',

            'contact_name'          =>  '请上传超级管理员姓名(该姓名需与法人身份证姓名一致)',

            'id_card'               =>  '请上传超级管理身份证号',

            'mobile_phone'          =>  '请上传超级管理员手机号',

            'id_card_copy'          =>  '请上传超级管理身份证人像面照地址',

            'id_card_national'      =>  '请上传超级管理身份证国徽面照片地址',

            'id_card_valid_time'    =>  '请上传超级管理身份证有效期限',

            'store_name'            =>  '请上传店铺名称',

            'merchant_shortname'    =>  '请上传商户简称',

            'store_qr_code'         =>  '请上传店铺二维码图片地址'

        ];



        //判断参数是否为空

        foreach ($error_array as $key => $value) {

            if (empty($userinfo[$key])) {

                throw new \RuntimeException($value);

            }

        }



        $keyPath            =   $this->keyPath;



        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书



        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048'; //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/applyments/'; //二级商户进件注册地址

        if(empty($userinfo['merchant_shortname'])){
            $userinfo['merchant_shortname'] = "洗美养车";
        }

        $data               =   [



            'out_request_no'        =>  $userinfo['out_request_no'], //业务申请编号

            'organization_type'     =>  '2401', //主体类型

            'need_account_info'     =>  false, //是否填写结算银行账户

            'contact_info'          =>  [

                'contact_type'              =>  '65', //超级管理员类型，1、主体为“小微/个人卖家 ”，可选择：65-经营者/法人。

                'contact_name'              =>  $this->getEncrypt($userinfo['contact_name'],$api_cert), //超级管理员姓名 该姓名需与法人身份证姓名一致。

                'contact_id_card_number'    =>  $this->getEncrypt($userinfo['id_card'],$api_cert), //法人身份证号

                'mobile_phone'              =>  $this->getEncrypt($userinfo['mobile_phone'],$api_cert), //超级管理员手机  

            ],//超级管理员信息

            'id_card_info'          =>  [

                'id_card_copy'              =>  $this->upLoadFile('.'.$userinfo['id_card_copy']), //身份证人像面照

                'id_card_national'          =>  $this->upLoadFile('.'.$userinfo['id_card_national']), //身份证国徽面照片

                'id_card_name'              =>  $this->getEncrypt($userinfo['contact_name'],$api_cert), //身份证姓名

                'id_card_number'            =>  $this->getEncrypt($userinfo['id_card'],$api_cert), //身份证号码

                'id_card_valid_time'        =>  $userinfo['id_card_valid_time'] //身份证有效期限

            ], //身份证信息

            'sales_scene_info'      => [

                'store_name'                => $userinfo['store_name'], //店铺名称

                'store_qr_code'             => $this->upLoadFile('.'.$userinfo['store_qr_code']), //店铺二维码

            ],//店铺信息

            'merchant_shortname'    => $userinfo['merchant_shortname'] //商户简称

            // 'merchant_shortname'    => "洗美养车" //商户简称



        ];



        if ($userinfo['account_number']) {

            $userinfo['account_name'] = str_replace(' ','',$userinfo['account_name']);

            $data['need_account_info']      =  true;

            $data['account_info']           =  [

                'bank_account_type'             =>  '75',  //账户类型,主体为“小微/个人卖家”，可选择：75-对私账户

                'account_bank'                  =>  $userinfo['account_bank'],  //开户银行

                'account_name'                  =>  $this->getEncrypt($userinfo['account_name'],$api_cert),  //开户名称

                'bank_address_code'             =>  $userinfo['bank_address_code'], //开户地址代码

                'account_number'                =>  $this->getEncrypt($userinfo['account_number'],$api_cert)  //银行帐号

            ];

        }



        $filestr    =   json_encode($data);

        $time       =   time();

        $nonce_str  =   md5(time().mt_rand(0,1000));

        $pkid       =   file_get_contents($keyPath);



        $token      =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);

    }



    /**

     * 入驻商家，成为二级商户(小V商户)

     * 

     * @param  Array    $userinfo      订单信息

     *                  [

     *                      out_request_no      业务申请编号

     *                      contact_name        超级管理员姓名 该姓名需与法人身份证姓名一致

     *                      id_card             超级管理身份证号

     *                      mobile_phone        超级管理员手机号

     *                      id_card_copy        超级管理身份证人像面照地址

     *                      id_card_national    超级管理身份证国徽面照片地址

     *                      id_card_valid_time  超级管理身份证有效期限

     *                      store_name          店铺名称

     *                      merchant_shortname  商户简称

     *                      store_qr_code       店铺二维码图片地址

     *                  ]                

     * 

     * @return Array                    二级商户申请信息

     */

    public function er_shop_user_shell($userinfo){

        

        $error_array        =   [

            'out_request_no'        =>  '请上传业务申请编号',

            'contact_name'          =>  '请上传超级管理员姓名(该姓名需与法人身份证姓名一致)',

            'id_card'               =>  '请上传超级管理身份证号',

            'mobile_phone'          =>  '请上传超级管理员手机号',

            'id_card_copy'          =>  '请上传超级管理身份证人像面照地址',

            'id_card_national'      =>  '请上传超级管理身份证国徽面照片地址',

            'id_card_valid_time'    =>  '请上传超级管理身份证有效期限',

            'store_name'            =>  '请上传店铺名称',

            'merchant_shortname'    =>  '请上传商户简称',

            'store_qr_code'         =>  '请上传店铺二维码图片地址',

        ];



        //判断参数是否为空

        foreach ($error_array as $key => $value) {

            if (empty($userinfo[$key])) {

                throw new \RuntimeException($value);

            }

        }



        $keyPath            =   $this->keyPath;



        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息

        // var_dump($pingtai_list);exit;



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书



        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048'; //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/applyments/'; //二级商户进件注册地址



        $data               =   [



            'out_request_no'        =>  $userinfo['out_request_no'], //业务申请编号

            'organization_type'     =>  '2500', //主体类型

            // 'need_account_info'     =>  false, //是否填写结算银行账户 2022/07/01 废弃

            'contact_info'          =>  [

                'contact_type'              =>  '65', //超级管理员类型，1、主体为“小微/个人卖家 ”，可选择：65-经营者/法人。

                'contact_name'              =>  $this->getEncrypt($userinfo['contact_name'],$api_cert), //超级管理员姓名 该姓名需与法人身份证姓名一致。

                'contact_id_card_number'    =>  $this->getEncrypt($userinfo['id_card'],$api_cert), //法人身份证号

                'mobile_phone'              =>  $this->getEncrypt($userinfo['mobile_phone'],$api_cert), //超级管理员手机  

            ],//超级管理员信息

            'id_card_info'          =>  [

                'id_card_copy'              =>  $this->upLoadFile('.'.$userinfo['id_card_copy']), //身份证人像面照

                'id_card_national'          =>  $this->upLoadFile('.'.$userinfo['id_card_national']), //身份证国徽面照片

                'id_card_name'              =>  $this->getEncrypt($userinfo['contact_name'],$api_cert), //身份证姓名

                'id_card_number'            =>  $this->getEncrypt($userinfo['id_card'],$api_cert), //身份证号码

                'id_card_valid_time'        =>  $userinfo['id_card_valid_time'], //身份证有效期限

                'id_card_valid_time_begin'  =>  $userinfo['id_card_valid_start_time']//身份证有效期开始时间2022/07/07 添加

            ], //身份证信息

            'sales_scene_info'      =>  [

                'store_name'                => $userinfo['store_name'], //店铺名称

                'store_qr_code'             => $this->upLoadFile('.'.$userinfo['store_qr_code']), //店铺二维码

            ],//店铺信息

            'merchant_shortname'    =>  $userinfo['merchant_shortname'], //商户简称

            'business_addition_desc'=>  '该商户已持续从事电子商务经营活动满6个月，且期间经营收入累计超过20万元。'

        ];



        if ($userinfo['account_number']) {

            $userinfo['account_name'] = str_replace(' ','',$userinfo['account_name']);

            // $data['need_account_info']      =  true; // 2022/07/01 废弃

            $data['account_info']           =  [

                'bank_account_type'             =>  '75',  //账户类型,主体为“小微/个人卖家”，可选择：75-对私账户

                'account_bank'                  =>  $userinfo['account_bank'],  //开户银行

                'account_name'                  =>  $this->getEncrypt($userinfo['account_name'],$api_cert),  //开户名称

                'bank_address_code'             =>  $userinfo['bank_address_code'], //开户地址代码

                'account_number'                =>  $this->getEncrypt($userinfo['account_number'],$api_cert)  //银行帐号

            ];

        }



        $filestr    =   json_encode($data);

        $time       =   time();

        $nonce_str  =   md5(time().mt_rand(0,1000));

        $pkid       =   file_get_contents($keyPath);



        $token      =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);

        // var_dump($token);exit;



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);

    }



    /**

     * 入驻商家，成为二级商户(个体工商户)

     * 

     * @param  Array    $userinfo      订单信息

     *                  [

     *                      out_request_no      业务申请编号

     *                      contact_name        超级管理员姓名 该姓名需与法人身份证姓名一致

     *                      id_card             超级管理身份证号

     *                      mobile_phone        超级管理员手机号

     *                      id_card_copy        超级管理身份证人像面照地址

     *                      id_card_national    超级管理身份证国徽面照片地址

     *                      id_card_valid_time  超级管理身份证有效期限

     *                      store_name          店铺名称

     *                      merchant_shortname  商户简称

     *                      store_qr_code       店铺二维码图片地址

     *                  ]                

     * 

     * @return Array                    二级商户申请信息

     */

    public function er_shop_individual($userinfo){

        

        $error_array        =   [

            'out_request_no'            =>  '请上传业务申请编号',

            'contact_name'              =>  '请上传超级管理员姓名(该姓名需与法人身份证姓名一致)',

            'id_card'                   =>  '请上传超级管理身份证号',

            'mobile_phone'              =>  '请上传超级管理员手机号',

            'id_card_copy'              =>  '请上传超级管理身份证人像面照片',

            'id_card_national'          =>  '请上传超级管理身份证国徽面照片',

            'id_card_valid_time'        =>  '请上传超级管理身份证有效期限',

            'store_name'                =>  '请上传店铺名称',

            'merchant_shortname'        =>  '请上传商户简称',

            'store_qr_code'             =>  '请上传店铺二维码图片',

            'business_license_copy'     =>  '请上传营业执照',

            'business_license_number'   =>  '请上传营业执照上的注册号/统一社会信用代码',

            'contact_email'             =>  '请上传超级管理员邮箱'

        ];



        //判断参数是否为空

        foreach ($error_array as $key => $value) {

            if (empty($userinfo[$key])) {

                throw new \RuntimeException($value);

            }

        }



        $keyPath            =   $this->keyPath;



        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书



        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048'; //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/applyments/'; //二级商户进件注册地址

        if(empty($userinfo['merchant_shortname'])){
            $userinfo['merchant_shortname'] = "洗美养车";
        }

        $data               =   [



            'out_request_no'        =>  $userinfo['out_request_no'], //业务申请编号

            'organization_type'     =>  '4', //主体类型

            'business_license_info' =>  [

                'business_license_copy'     =>  $this->upLoadFile('.'.$userinfo['business_license_copy']),//营业执照的证件图片

                'business_license_number'   =>  $userinfo['business_license_number'],//营业执照上的注册号/统一社会信用代码，须为15位数字或 18位数字|大写字母

                //'merchant_name'             =>  '个体户'.$userinfo['contact_name'],//营业执照/登记证书的商家名称

                'merchant_name'             =>  $userinfo['contact_name'],//营业执照/登记证书的商家名称

                'legal_person'              =>  $userinfo['realname'],//证件的经营者/法定代表人姓名

            ],

            // 'need_account_info'     =>  false, //是否填写结算银行账户 2022/07/01 废弃

            'contact_info'          =>  [

                'contact_type'              =>  '65', //超级管理员类型，1、主体为“小微/个人卖家 ”，可选择：65-经营者/法人。

                'contact_name'              =>  $this->getEncrypt($userinfo['realname'],$api_cert), //超级管理员姓名 该姓名需与法人身份证姓名一致。

                'contact_id_card_number'    =>  $this->getEncrypt($userinfo['id_card'],$api_cert), //法人身份证号

                'mobile_phone'              =>  $this->getEncrypt($userinfo['mobile_phone'],$api_cert), //超级管理员手机  

                'contact_email'             =>  $this->getEncrypt($userinfo['contact_email'],$api_cert), //超级管理员邮箱  

            ],//超级管理员信息

            'id_card_info'          =>  [

                'id_card_copy'              =>  $this->upLoadFile('.'.$userinfo['id_card_copy']), //身份证人像面照

                'id_card_national'          =>  $this->upLoadFile('.'.$userinfo['id_card_national']), //身份证国徽面照片

                'id_card_name'              =>  $this->getEncrypt($userinfo['realname'],$api_cert), //身份证姓名

                'id_card_number'            =>  $this->getEncrypt($userinfo['id_card'],$api_cert), //身份证号码

                'id_card_valid_time'        =>  $userinfo['id_card_valid_time'], //身份证有效期限

                'id_card_valid_time_begin'  => $userinfo['id_card_valid_start_time']//身份证有效期开始时间2022/07/07 添加

            ], //身份证信息

            'sales_scene_info'      => [

                'store_name'                => $userinfo['store_name'], //店铺名称

                'store_qr_code'             => $this->upLoadFile('.'.$userinfo['store_qr_code']), //店铺二维码

            ],//店铺信息

            'merchant_shortname'    => $userinfo['merchant_shortname']//商户简称



        ];



        if ($userinfo['account_number']) {

            $userinfo['account_name'] = str_replace(' ','',$userinfo['account_name']);

            // $data['need_account_info']      =  true;// 2022/07/01 废弃

            $data['account_info']           =  [

                'bank_account_type'             =>  '75',  //账户类型,主体为“小微/个人卖家”，可选择：75-对私账户

                'account_bank'                  =>  $userinfo['account_bank'],  //开户银行

                'account_name'                  =>  $this->getEncrypt($userinfo['account_name'],$api_cert),  //开户名称

                'bank_address_code'             =>  $userinfo['bank_address_code'], //开户地址代码

                'bank_branch_id'                =>  '',

                'bank_name'                     =>  '',

                'account_number'                =>  $this->getEncrypt($userinfo['account_number'],$api_cert)  //银行帐号

            ];

        }



        $filestr    =   json_encode($data);

        $time       =   time();

        $nonce_str  =   md5(time().mt_rand(0,1000));

        $pkid       =   file_get_contents($keyPath);



        $token      =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);

    }

      /**

     * 入驻商家，成为二级商户(公司/企业)

     * 

     * @param  Array    $userinfo      订单信息

     *                  [

     *                      out_request_no      业务申请编号

     *                      contact_name        超级管理员姓名 该姓名需与法人身份证姓名一致

     *                      id_card             超级管理身份证号

     *                      mobile_phone        超级管理员手机号

     *                      id_card_copy        超级管理身份证人像面照地址

     *                      id_card_national    超级管理身份证国徽面照片地址

     *                      id_card_valid_time  超级管理身份证有效期限

     *                      store_name          店铺名称

     *                      merchant_shortname  商户简称

     *                      store_qr_code       店铺二维码图片地址

     *                  ]                

     * 

     * @return Array                    二级商户申请信息

     */

    public function er_shop_individuals($userinfo){

        

        $error_array        =   [

            'out_request_no'            =>  '请上传业务申请编号',

            'contact_name'              =>  '请上传超级管理员姓名(该姓名需与法人身份证姓名一致)',

            'id_card'                   =>  '请上传超级管理身份证号',

            'mobile_phone'              =>  '请上传超级管理员手机号',

            'id_card_copy'              =>  '请上传超级管理身份证人像面照片',

            'id_card_national'          =>  '请上传超级管理身份证国徽面照片',

            'id_card_valid_time'        =>  '请上传超级管理身份证有效期限',

            'store_name'                =>  '请上传店铺名称',

            'merchant_shortname'        =>  '请上传商户简称',

            'store_qr_code'             =>  '请上传店铺二维码图片',

            'business_license_copy'     =>  '请上传营业执照',

            'business_license_number'   =>  '请上传营业执照上的注册号/统一社会信用代码',

            'contact_email'             =>  '请上传超级管理员邮箱'

        ];



        //判断参数是否为空

        foreach ($error_array as $key => $value) {

            if (empty($userinfo[$key])) {

                throw new \RuntimeException($value);

            }

        }

        // dump($userinfo);die;

        $keyPath            =   $this->keyPath;



        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书



        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048'; //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/applyments/'; //二级商户进件注册地址



        $data               =   [



            'out_request_no'        =>  $userinfo['out_request_no'], //业务申请编号

            'organization_type'     =>  '2', //主体类型

            'business_license_info' =>  [

                'business_license_copy'     =>  $this->upLoadFile('.'.$userinfo['business_license_copy']),//营业执照的证件图片

                'business_license_number'   =>  $userinfo['business_license_number'],//营业执照上的注册号/统一社会信用代码，须为15位数字或 18位数字|大写字母

                'merchant_name'             =>  $userinfo['contact_name'],//营业执照/登记证书的商家名称

                'legal_person'              =>  $userinfo['realname'],//证件的经营者/法定代表人姓名

            ],

            'id_card_info'          =>  [

                'id_card_copy'              =>  $this->upLoadFile('.'.$userinfo['id_card_copy']), //身份证人像面照

                'id_card_national'          =>  $this->upLoadFile('.'.$userinfo['id_card_national']), //身份证国徽面照片

                'id_card_name'              =>  $this->getEncrypt($userinfo['realname'],$api_cert), //身份证姓名

                'id_card_number'            =>  $this->getEncrypt($userinfo['id_card'],$api_cert), //身份证号码

                'id_card_valid_time'        =>  $userinfo['id_card_valid_time'], //身份证有效期限

                'id_card_valid_time_begin'  =>  $userinfo['id_card_valid_start_time'],//身份证有效期开始时间2022/07/01添加

                'id_card_address'           =>  $this->getEncrypt($userinfo['id_card_arddress'],$api_cert)//身份证居住地址2022/07/01添加

            ], //身份证信息

            // 'need_account_info'     =>  false, //是否填写结算银行账户 2022/07/01 废弃

            'contact_info'          =>  [

                'contact_type'              =>  '65', //超级管理员类型，1、主体为“小微/个人卖家 ”，可选择：65-经营者/法人。

                'contact_name'              =>  $this->getEncrypt($userinfo['realname'],$api_cert), //超级管理员姓名 该姓名需与法人身份证姓名一致。

                'contact_id_card_number'    =>  $this->getEncrypt($userinfo['id_card'],$api_cert), //法人身份证号

                'mobile_phone'              =>  $this->getEncrypt($userinfo['mobile_phone'],$api_cert), //超级管理员手机  

                'contact_email'             =>  $this->getEncrypt($userinfo['contact_email'],$api_cert), //超级管理员邮箱  

            ],//超级管理员信息

           

            'sales_scene_info'      => [

                'store_name'                => $userinfo['store_name'], //店铺名称

                'store_qr_code'             => $this->upLoadFile('.'.$userinfo['store_qr_code']), //店铺二维码

            ],//店铺信息

            'merchant_shortname'    => $userinfo['merchant_shortname'] //商户简称



        ];



        if ($userinfo['account_number']) {

            $userinfo['account_name'] = str_replace(' ','',$userinfo['account_name']);

            // $data['need_account_info']      =  true;//2022/07/01 废弃

            $data['account_info']           =  [

                'bank_account_type'             =>  '74',  //账户类型,主体为“小微/个人卖家”，可选择：75-对私账户

                'account_bank'                  =>  $userinfo['account_bank'],  //开户银行

                'account_name'                  =>  $this->getEncrypt($userinfo['account_name'],$api_cert),  //开户名称

                'bank_address_code'             =>  $userinfo['bank_address_code'], //开户地址代码

                'account_number'                =>  $this->getEncrypt($userinfo['account_number'],$api_cert)  //银行帐号

            ];

        }



        $filestr    =   json_encode($data);

        $time       =   time();

        $nonce_str  =   md5(time().mt_rand(0,1000));

        $pkid       =   file_get_contents($keyPath);



        $token      =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        // dump($data);die;

       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);

    }

    public function teyue_shop_individuals($userinfo){

        

        $error_array        =   [

            // 'out_request_no'            =>  '请上传业务申请编号',

            // 'contact_name'              =>  '请上传超级管理员姓名(该姓名需与法人身份证姓名一致)',

            // 'id_card'                   =>  '请上传超级管理身份证号',

            // 'mobile_phone'              =>  '请上传超级管理员手机号',

            // 'id_card_copy'              =>  '请上传超级管理身份证人像面照片',

            // 'id_card_national'          =>  '请上传超级管理身份证国徽面照片',

            // 'id_card_valid_time'        =>  '请上传超级管理身份证有效期限',

            // 'store_name'                =>  '请上传店铺名称',

            // 'merchant_shortname'        =>  '请上传商户简称',

            // 'store_qr_code'             =>  '请上传店铺二维码图片',

            // 'business_license_copy'     =>  '请上传营业执照',

            // 'business_license_number'   =>  '请上传营业执照上的注册号/统一社会信用代码',

            // 'contact_email'             =>  '请上传超级管理员邮箱'

        ];



        //判断参数是否为空

        foreach ($error_array as $key => $value) {

            if (empty($userinfo[$key])) {

                throw new \RuntimeException($value);

            }

        }

        // dump($userinfo);die;

        $keyPath            =   $this->keyPath;



        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书



        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048'; //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/'; //特约商户进件注册地址

        // $aa=$this->upLoadFile('.'.$userinfo['business_license_copy']);
        // var_dump($aa);die;


        $data               =   [



            'business_code'        =>  $userinfo['out_request_no'], //业务申请编号
            'contact_info'          =>  [

                'contact_type'              =>  'LEGAL', //法人。

                'contact_name'              =>  $this->getEncrypt($userinfo['realname'],$api_cert), //超级管理员姓名 该姓名需与法人身份证姓名一致。

                'contact_id_number'    =>  $this->getEncrypt($userinfo['id_card'],$api_cert), //法人身份证号

                'mobile_phone'              =>  $this->getEncrypt($userinfo['mobile_phone'],$api_cert), //超级管理员手机  

                'contact_email'             =>  $this->getEncrypt($userinfo['contact_email'],$api_cert), //超级管理员邮箱  

                // 'contact_id_doc_copy' => $this->upLoadFile('.'.$userinfo['id_card_copy']),//身份证正面
                // 'contact_id_doc_copy_back' =>$this->upLoadFile('.'.$userinfo['id_card_national']),//反面
            ],//超级管理员信息
            'subject_info'          =>  [

                'subject_type'              =>  $userinfo['subject_type'], //主体类型。SUBJECT_TYPE_INDIVIDUAL（个体户）：营业执照上的主体类型一般为个体户、个体工商户、个体经营；SUBJECT_TYPE_ENTERPRISE（企业）：营业执照上的主体类型一般为有限公司、有限责任公司；

                'business_license_info'              =>  [
                    'license_copy'=>$this->upLoadFile('.'.$userinfo['business_license_copy']),//营业执照的证件图片,//营业执照照片
                    'license_number'=>$userinfo['business_license_number'],//营业执照上的注册号/统一社会信用代码，须为15位数字或 18位数字|大写字母
                    'merchant_name' =>  $userinfo['merchant_name'], //商户名称。个体户证件为以下情况时，按照个体户XXX命名（XXX是营业执照经营人姓名）：营业执照登记名称为空、仅含数字、仅含特殊字符、“无”、“无字号”
                    'legal_person' =>  $userinfo['realname'],//法人姓名
                    'license_address' =>  $userinfo['license_address'],//注册地址
                    // 'period_begin' =>  $userinfo['period_begin'],//建议填写营业执照的有效期限开始时间
                    // 'period_end' =>  $userinfo['period_end'],
                ], 
                'identity_info'              =>  [
                    'id_holder_type'=>'LEGAL',//法人
                    'id_doc_type'=>'IDENTIFICATION_TYPE_IDCARD',//身份证
                    'id_card_info'              =>  [
                        'id_card_copy'=>$this->upLoadFile('.'.$userinfo['id_card_copy']),//身份证正面
                        'id_card_national'=>$this->upLoadFile('.'.$userinfo['id_card_national']),//反面
                        'id_card_name'=>$this->getEncrypt($userinfo['realname'],$api_cert),//法人姓名
                        'id_card_number'=>$this->getEncrypt($userinfo['id_card'],$api_cert), //法人身份证号
                        'id_card_address'=>$this->getEncrypt($userinfo['id_card_arddress'],$api_cert), //身份证居住地
                        'card_period_begin'=>$userinfo['id_card_valid_start_time'],//身份证有效期开始时间2022-01-01添加
                        'card_period_end'=>$userinfo['id_card_valid_time'],//身份证有效期结束时间
                    ], 
                ], 
                

            ],//主体资料
            'business_info'          =>  [

                'merchant_shortname'              =>  $userinfo['store_name'], //简称。

                'service_phone'              =>  $userinfo['mobile_phone'], //。
                'sales_info'          =>  [

                    'sales_scenes_type'              =>  ['SALES_SCENES_MINI_PROGRAM'], //小程序
    
                    'mini_program_info'              =>  [
                        'mini_program_appid'=>'wxf0572df6663fae1d',//服务商appid
                        'mini_program_pics'=>[$this->upLoadFile('.'.$userinfo['business_license_copy'])],//小程序截图
                    ], 
    
    
                ],

            ],
            


            'settlement_info' =>  [

                'settlement_id'     =>  $userinfo['settlement_id'],//入驻结算规则ID

                'qualification_type'   =>  '电商平台',//填写指定行业名称

            ],

         

            'bank_account_info'      => [

                'bank_account_type'                => $userinfo['bank_account_type'], //BANK_ACCOUNT_TYPE_CORPORATE：对公银行账户 BANK_ACCOUNT_TYPE_PERSONAL：经营者个人银行卡

                'account_name'             => $this->getEncrypt($userinfo['account_name'],$api_cert),  //开户名称

                'account_bank'     =>     $userinfo['account_bank'],  //开户银行
                'bank_address_code'             =>  $userinfo['bank_address_code'], //开户地址代码
                'account_number'                =>  $this->getEncrypt($userinfo['account_number'],$api_cert)  //银行帐号

            ],//店铺信息

           


        ];




        $filestr    =   json_encode($data);

        $time       =   time();

        $nonce_str  =   md5(time().mt_rand(0,1000));

        $pkid       =   file_get_contents($keyPath);



        $token      =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        // dump($data);die;

       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);

    }
    //添加分账接收方
    public function add_receivers($userinfo){

        

       

        // dump($userinfo);die;

        $keyPath            =   $this->keyPath;



        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书



        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048'; //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/profitsharing/receivers/add'; //特约商户进件注册地址

        // $aa=$this->upLoadFile('.'.$userinfo['business_license_copy']);
        // var_dump($aa);die;


        $data               =   [


            'sub_mchid'    => $userinfo['sub_mchid'],
            'appid'        =>  $this->appId, 
            'type'        =>  $userinfo['type'], 
            'account'        =>  $userinfo['account'], 
            'relation_type'        =>  'SERVICE_PROVIDER', 
            

        ];




        $filestr    =   json_encode($data);

        $time       =   time();

        $nonce_str  =   md5(time().mt_rand(0,1000));

        $pkid       =   file_get_contents($keyPath);



        $token      =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        // dump($data);die;

       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);

    }
    //请求分账
    public function receivers($userinfo){

        

       

        // dump($userinfo);die;

        $keyPath            =   $this->keyPath;



        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书



        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048'; //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/profitsharing/orders'; //

        // $aa=$this->upLoadFile('.'.$userinfo['business_license_copy']);
        // var_dump($aa);die;

        // $receivers[]=[
        //     'type' => $userinfo['type'],
        //     'account' => $userinfo['account'],
        //     'amount' =>$userinfo['price'],
        //     'description' =>'供应商货款',
        // ];
        $data               =   [


            'sub_mchid'     =>  $userinfo['sub_mchid'],
            'appid'        =>  $this->appId, 
            'transaction_id'        =>  $userinfo['transaction_id'], 
            'out_order_no'        =>  $userinfo['out_order_no'], 
            'receivers'=>$userinfo['receivers'],//分账接收方
            'unfreeze_unsplit'        =>  true, 
            

        ];




        $filestr    =   json_encode($data);

        $time       =   time();

        $nonce_str  =   md5(time().mt_rand(0,1000));

        $pkid       =   file_get_contents($keyPath);



        $token      =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        // dump($data);die;

       $result = PublicCurl($url,true,'post',$filestr,$header);

       var_dump($result);die;

       return json_decode($result,true);

    }

    //完结分账
    public function finsh_order($userinfo){

        

       

        // dump($userinfo);die;

        $keyPath            =   $this->keyPath;



        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书



        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048'; //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/profitsharing/orders/unfreeze'; 

        // $aa=$this->upLoadFile('.'.$userinfo['business_license_copy']);
        // var_dump($aa);die;


        $data               =   [


            'sub_mchid'            =>   $userinfo['sub_mchid'],
            'transaction_id'        =>  $userinfo['transaction_id'], 
            'out_order_no'        =>  $userinfo['out_order_no'], 
            
            'description'        =>  '门店货款收入', 
            

        ];




        $filestr    =   json_encode($data);

        $time       =   time();

        $nonce_str  =   md5(time().mt_rand(0,1000));

        $pkid       =   file_get_contents($keyPath);



        $token      =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        // dump($data);die;

       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);

    }
    public function refund($userinfo){

        

       

        // dump($userinfo);die;

        $keyPath            =   $this->keyPath;



        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书



        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048'; //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/refund/domestic/refunds'; 

        // $aa=$this->upLoadFile('.'.$userinfo['business_license_copy']);
        // var_dump($aa);die;


        $data               =   [

            'sub_mchid'             =>  $userinfo['sub_mchid'],
            'transaction_id'        =>  $userinfo['transaction_id'],
            'out_refund_no'        =>  $userinfo['out_refund_no'], 
            'amount'        =>  [
                'refund'   =>$userinfo['refund'],
                'total'    =>$userinfo['total'],
                'currency' =>'CNY',
            ], 
            

        ];




        $filestr    =   json_encode($data);

        $time       =   time();

        $nonce_str  =   md5(time().mt_rand(0,1000));

        $pkid       =   file_get_contents($keyPath);



        $token      =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        // dump($data);die;

       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);

    }
    //查询分账结果
    public function look_finsh($userinfo){

        

       

        // dump($userinfo);die;

        $url = 'https://api.mch.weixin.qq.com/v3/profitsharing/orders/'.$userinfo['out_order_no'].'?sub_mchid='.$userinfo['sub_mchid'].'&transaction_id='.$userinfo['transaction_id']; 


        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);



        return json_decode($result,true);


    }
    /**

     * 查询特约商户进件状态结果(applymentid)

     * @param  String   $applymentid    商户进件结果id

     * @return Array                    商户进件状态结果

     */

    public function get_shop_result_teyue($applymentid = ''){

        

        if (empty($applymentid)) {

            throw new \RuntimeException('参数 $applymentid 不可为空');

        }



        $url            =   'https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/applyment_id/'.$applymentid;

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);



        return json_decode($result,true);

    }

    /**

     * 查询二级商户进件状态结果(applymentid)

     * @param  String   $applymentid    二级商户进件结果id

     * @return Array                    商户进件状态结果

     */

    public function get_shop_result_a($applymentid = ''){

        

        if (empty($applymentid)) {

            throw new \RuntimeException('参数 $applymentid 不可为空');

        }



        $url            =   'https://api.mch.weixin.qq.com/v3/ecommerce/applyments/'.$applymentid;

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);



        return json_decode($result,true);

    }

    /**

     * 查询二级商户进件状态结果(out_request_no)

     * @param  String   $applymentid    二级商户进件结果id

     * @return Array                    商户进件状态结果

     */

    public function get_shop_result_o($out_request_no = ''){

        

        if (empty($out_request_no)) {

            throw new \RuntimeException('参数 $out_request_no 不可为空');

        }



        $url            =   'https://api.mch.weixin.qq.com/v3/ecommerce/applyments/out-request-no/'.$out_request_no;

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);



        return json_decode($result,true);

    }



    /**

     * 获取平台证书列表

     * 

     * @return Array    证书列表

     */

    public function get_pingtai_list(){

        $keyPath        =   $this->keyPath;



        $url            =   'https://api.mch.weixin.qq.com/v3/certificates';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $filestr        =   "";

        $pkid           =   file_get_contents($keyPath);

        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;



        $schema         =   'WECHATPAY2-SHA256-RSA2048';



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,"",$pkid,$merchant_id,$serial_no);



        $header[]       =   'User-Agent:https://zh.wikipedia.org/wiki/User_agent';

        $header[]       =   'Accept:application/json';

        $header[]       =   'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $token;



        $ch             =   curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 2);

        $output         =   curl_exec($ch);

        curl_close($ch);

        return (json_decode($output,true));

    }



    /**

     * 重要信息加密

     * 

     * @param  String   $str        需要加密的字符串

     * @param  String   $api_cert   加密需要的证书，为空时获取服务商的证书

     * 

     * @return String               加密后的字符串

     */

    private function getEncrypt($str,$api_cert=''){ 



        $apiclient_cert =   $this->apiclient_cert; 

        $public_key     =   file_get_contents($apiclient_cert); 



        if (!empty($api_cert)) {

            $public_key =   $api_cert;

        }



        $encrypted      =   ''; 



        if (openssl_public_encrypt($str,$encrypted,$public_key,OPENSSL_PKCS1_OAEP_PADDING)) { 

            //base64编码 

            $sign       =   base64_encode($encrypted);

        } else {

            throw new Exception('encrypt failed');

        }



        return $sign;

    }



    /**

     * 重要信息解密

     * 

     * @param  String   $str        需要解密的字符串

     * @param  String   $api_cert   解密需要的证书，为空时获取服务商的证书

     * 

     * @return String               解密后的字符串

     */

    public function getDecrypt($str,$api_cert=''){ 



        $keyPath        =   $this->keyPath; 

        $public_key     =   file_get_contents($keyPath);



        if (!empty($api_cert)) {

            $public_key =   $api_cert;

        }



        $encrypted      =   ''; 



        //私钥解密

        $private_key = openssl_pkey_get_private($public_key);



        if (!$private_key) {

            throw new \RuntimeException('私钥不可用');

        }



        openssl_private_decrypt(base64_decode($str), $dcyCont, $private_key,OPENSSL_PKCS1_OAEP_PADDING);

        

        if(!$dcyCont){

            throw new \RuntimeException(openssl_error_string());

        }



        return $dcyCont;

    }



    /**

     * 上传图片获取media_id

     * @param  String   $file_path  需要上传图片的地址

     * 

     * @return String               获取图片上传后微信的media_id

     */

    public function upLoadFile($file_path){
        // var_dump($file_path);

        header("Content-type:text/html;charset=utf-8");

        $url            =   'https://api.mch.weixin.qq.com/v3/merchant/media/upload';

        $filePath       =   $file_path;

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';



        $mess           =   $this->binaryEncodeImage($filePath);
        // var_dump($mess);

        $filestr        =   json_encode(array('filename' => 'mb.png','sha256'=>hash_file("sha256", $filePath)));



        // 准备参与签名数据

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);


        $token          =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);

        // var_dump($token);


        // 设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:multipart/form-data;boundary=7derenufded" //切记boundary=后面这里切记这里不要加-- 和 “”

        ];

            

        // 这里是构造请求body

        $boundary       =   '7derenufded';

        $boundarystr    =   "--{$boundary}\r\n";

 

        $out            =   $boundarystr;

        $out           .=   'Content-Disposition:form-data;name="meta"'."\r\n"; //name必须是meta

        $out           .=   'Content-Type:image/jpeg; charset=UTF-8'."\r\n";

        $out           .=   "\r\n";

        $out           .=   "".$filestr."\r\n";

        $out           .=    $boundarystr;

        $out           .=   'Content-Disposition:form-data;name="file";filename="mb.png"'."\r\n"; //name必须是file

        $out           .=   'Content-Type: image/png'."\r\n";

        $out           .=   "\r\n";

        $out           .=   $mess."\r\n";

        $out           .=   "--{$boundary}--";



        $curl           =   curl_init();

        curl_setopt($curl, CURLOPT_URL, $url);

        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);

        curl_setopt($curl, CURLOPT_POST, true);

        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

        curl_setopt($curl, CURLOPT_POSTFIELDS,$out);

        curl_setopt($curl, CURLOPT_HEADER, false);

        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

        $response       =   json_decode(curl_exec($curl),true);

        // var_dump(curl_error($curl));

        return $response['media_id'];

    }



    /**

     * 生成签名

     * 

     * @param  String   $url                API请求地址

     * @param  String   $http_method        请求方式（GET,POST,PUT等）

     * @param  String   $timestamp          时间戳

     * @param  String   $nonce              随机串

     * @param  String   $body               请求报文主体

     * @param  String   $mch_private_key    加密用的私钥

     * @param  String   $merchant_id        商户号

     * @param  String   $serial_no          商户API证书序列号

     * 

     * @return String                       生成好的签名

     */

    private function get_sign($url,$http_method,$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no){



        $url_parts      =   parse_url($url);

        $canonical_url  =   ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));

        $message        =

            $http_method    ."\n".

            $canonical_url  ."\n".

            $timestamp      ."\n".

            $nonce          ."\n".

            $body           ."\n";



        openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');

        $sign           =   base64_encode($raw_sign);

        // $schema         =   $this->schema;

        $token          =   sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',$merchant_id,$nonce,$timestamp,$serial_no,$sign);



        return $token;

    }



    /**

     * 生成支付签名

     * 

     * @param  Array    $body               需要签名的字段

     *                  [

     *                      appId           小程序、公众号 appid

     *                      timeStamp       时间戳

     *                      nonceStr        随机字符串(32位)

     *                      package         下单后返回的订单id prepay_id='.$prepay_id

     *                  ]

     * @param  String   $mch_private_key    加密需要的私钥

     * 

     * @return String                       生成的支付签名

     */

    private function get_pay_sign($body,$mch_private_key){



        $message        =



            $body['appId']      ."\n".

            $body['timeStamp']  ."\n".

            $body['nonceStr']   ."\n".

            $body['package']    ."\n";



        openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');

        $sign           =   base64_encode($raw_sign);

        return $sign;

    }



    /**

     * 图片转二进制

     * 

     * @param  String   $img_file   图片路径

     * 

     * @return String               二进制图片字符串

     */

    private function binaryEncodeImage($img_file){

        header("Content-type:text/html;charset=utf-8");



        $p_size         =   filesize($img_file);

        $img_binary     =   fread(fopen($img_file, "rb"), $p_size);



        return $img_binary;

    }



    /**

     * 支付

     * 

     * @param  Array    $orderinfo          订单需要的字段

     *                  [

     *                      he_order_num    合并支付单号

     *                      openid          支付人openid

     *                      notify_url      回调地址

     *                      order_lists     子单列表

     *                          [

     *                              attach          附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。示例值：深圳分店

     *                              total_amount    订单总金额，单位为分

     *                              out_trade_no    商户系统内部订单号

     *                              sub_mchid       二级商户号

     *                              description     商品描述

     *                              profit_sharing  是否指定分账 true：是 false：否

     *                          ]

     *                  ]

     * 

     * @return String                       生成的支付信息

     */

    public function user_pay($orderinfo,$order_form='1'){

        // dump($orderinfo);die;

        $url            =   'https://api.mch.weixin.qq.com/v3/combine-transactions/jsapi';

        $keyPath        =   $this->keyPath;



        // 子单数据

        $order_lists    =   [];



        // 判断子单数量（1-50）

        if (count($orderinfo['order_lists']) > 50 || count($orderinfo['order_lists']) == 0) {

            throw new \RuntimeException('子单列表数量为 1~50 条数据');

        }



        foreach ($orderinfo['order_lists'] as $key => $value) {

             // var_dump($value['attach']);exit;

            $attach_len = strlen($value['attach']);

            if($attach_len>128){//

                $value['attach'] = substr($value['attach'],0,80);//125

                $value['attach'] .= '...';

            }

            // var_dump($value['attach']);exit;

            // $attach_len = strlen($value['attach']);

            // var_dump($attach_len);exit;

            $sub_order  =   [

                    'mchid'             =>  $this->merchant_id, //子单发起方商户号，必须与发起方appid有绑定关系

                    'attach'            =>  $value['attach'], //附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。示例值：深圳分店

                    'amount'            =>  [

                        'total_amount'      =>  $value['total_amount'], //订单总金额，单位为分

                        'currency'          =>  'CNY' //符合ISO 4217标准的三位字母代码，人民币：CNY

                    ], //订单金额信息

                    'out_trade_no'      =>  $value['out_trade_no'], //商户系统内部订单号

                    'sub_mchid'         =>  $value['sub_mchid'], //二级商户号

                    'description'       =>  $value['description'], //商品描述

                    'settle_info'       =>  [

                        'profit_sharing'    =>  $value['profit_sharing'],//是否指定分账 true：是 false：否

                    ] //结算信息

                ];



            $order_lists[]          =   $sub_order; 

        }



        $data           =   [

            // 'combine_appid'         =>  $this->appId, //服务商公众号ID小程序ID

            'combine_mchid'         =>  $this->merchant_id, //服务商户号

            'combine_out_trade_no'  =>  $orderinfo['he_order_num'], //商户订单号

            'sub_orders'            =>  $order_lists, // 子单信息 最多50个子单

            'combine_payer_info'    =>  [

                'openid'                =>  $orderinfo['openid'] //用户在服务商appid下的唯一标识

            ], //支付者信息

            'notify_url'            =>  $orderinfo['notify_url'] //通知地址



        ];

        if($order_form=='1'){

            $data['combine_appid'] = $this->appId;

        }elseif($order_form=='3'){

            $data['combine_appid'] = $this->appId2;

        }else{

            $data['combine_appid'] = $this->appId1;

        }

        // var_dump($data);exit;

        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   json_encode($data);

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        // 设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        // dump($header);

        // dump($filestr);die;

        $result         =   PublicCurl($url,true,'post',$filestr,$header);

        // var_dump($result);die; 

        if(isset(json_decode($result,1)['message'])&&json_decode($result,1)['message']=="系统繁忙，请稍后重试"){

            return "系统繁忙，请稍后重试";

        }

        $prepay_id      =   json_decode($result,1)['prepay_id'];



        $js_time        =   time();

        $js_str         =   md5(time().mt_rand(0,1000));



        $js_data        =   [



            // 'appId'         =>  $this->appId, //公众号、小程序名称

            'timeStamp'     =>  ''.$js_time, //时间戳

            'nonceStr'      =>  $js_str, //随机串

            'package'       =>  'prepay_id='.$prepay_id //公众号、小程序名称



        ];

        if($order_form=='1'){

            $js_data['appId'] = $this->appId;

        }elseif($order_form=='3'){

            $js_data['appId'] = $this->appId2;

        }else{

            $js_data['appId'] = $this->appId1;

        }

        $token          =   $this->get_pay_sign($js_data,$pkid);



        $js_data['signType']    =   'RSA'; //微信签名方式

        $js_data['paySign']     =   $token; //微信签名

        

        return $js_data;

    }

     /**

     * 支付

     * 

     * @param  Array    $orderinfo          订单需要的字段

     *                  [

     *                      he_order_num    合并支付单号

     *                      openid          支付人openid

     *                      notify_url      回调地址

     *                      order_lists     子单列表

     *                          [

     *                              attach          附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。示例值：深圳分店

     *                              total_amount    订单总金额，单位为分

     *                              out_trade_no    商户系统内部订单号

     *                              sub_mchid       二级商户号

     *                              description     商品描述

     *                              profit_sharing  是否指定分账 true：是 false：否

     *                          ]

     *                  ]

     * 

     * @return String                       生成的支付信息

     */

    public function user_pay_native($orderinfo,$order_form='1'){

        // dump($orderinfo);die;

        $url            =   'https://api.mch.weixin.qq.com/v3/pay/partner/transactions/native';

        $keyPath        =   $this->keyPath;

        $data           =   [

            'sp_appid'         =>  $this->appId, //服务商公众号ID小程序ID

            'sp_mchid'         =>  $this->merchant_id, //服务商户号

            'sub_mchid'        =>  $orderinfo['sub_mchid'],//二级商户号

            'description'      => $orderinfo['description'],//描述

            'out_trade_no'  =>  $orderinfo['he_order_num'], //商户订单号

            'amount'            =>  [

                'total_amount'      =>  $orderinfo['total_amount'], //订单总金额，单位为分

                'currency'          =>  'CNY' //符合ISO 4217标准的三位字母代码，人民币：CNY

            ], //订单金额信息

            'settle_info'       =>  [

                'profit_sharing'    =>  $orderinfo['profit_sharing'],//是否指定分账 true：是 false：否

            ], //结算信息

            'notify_url'            =>  $orderinfo['notify_url'] //通知地址



        ];

       

        // var_dump($data);exit;

        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   json_encode($data);

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        // 设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        // dump($header);

        // dump($filestr);die;

        $result         =   PublicCurl($url,true,'post',$filestr,$header);

        $result = json_decode($result,1);

        if(isset($result['code_url'])){

            return $result['code_url'];

        }else{

            return "系统繁忙，请稍后重试";

        }

    }

    /**

     * 分账

     * 

     * @param  Array    $fields          需要的字段

     *                  [

     *                      sub_mchid       分账出资的电商平台二级商户

     *                      transaction_id  微信订单号

     *                      out_order_no    商户分账单号

     *                      receivers       分账接收方列表（最多50方）

     *                          [

     *                              mch_id          分账接收方账号

     *                              amount          分账金额，单位为分，只能为整数

     *                              description     分账的原因描述

     *                          ]

     *                  ]

     * 

     * @return String                       分账结果

     */

    public function profitsharing($fields,$order_form='1',$finish=false){



        $keyPath            =   $this->keyPath;

        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048';    //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders';



        $receivers          =   []; //分账接收方列表

        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息

        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号

        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书

        foreach ($fields['receivers'] as $key => $value) {

            $arr            =   [

                // 'type'              =>  'MERCHANT_ID',          //分账接收方类型，枚举值：MERCHANT_ID：商户、PERSONAL_OPENID：个人

                'receiver_account'  =>  $value['mch_id'],       //分账接收方账号：商户号（mch_id或者sub_mch_id）、个人openid

                'amount'            =>  intval($value['amount']),       //分账金额，单位为分，只能为整数

                'description'       =>  $value['description'],  //分账的原因描述，分账账单中需要体现

            ];

            if(empty($value['type'])){

                $value['type'] = '1';

            }

            if($value['type']=='1'){

                $arr['type'] = 'MERCHANT_ID';

            }else{

                $arr['type'] = 'PERSONAL_OPENID';

                // $arr['receiver_name'] = $this->getEncrypt($value['receiver_name'],$api_cert);//不传不校验

            }



            $receivers[]    = $arr;

        }



        $data               =   [

            // 'appid'             =>  $this->appId,                   //公众号、小程序的 appid

            'sub_mchid'         =>  $fields['sub_mchid'],        //分账出资的电商平台二级商户，填写微信支付分配的商户号

            'transaction_id'    =>  $fields['transaction_id'],   //微信订单号

            'out_order_no'      =>  $fields['out_order_no'],     //商户分账单号

            'receivers'         =>  $receivers,                     //分账接收方列表

            'finish'            =>  $finish                            //是否分账完成

        ];

        if($order_form=='1'){

            $data['appid'] = $this->appId;

        }elseif($order_form=='3'){

            $data['appid'] = $this->appId2;

        }else{

            $data['appid'] = $this->appId1;

        }

        

        $filestr            =   json_encode($data);

        $time               =   time();

        $nonce_str          =   md5(time().mt_rand(0,1000));

        $pkid               =   file_get_contents($keyPath);



        $token              =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header             =   [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



       $result = PublicCurl($url,true,'post',$filestr,$header);

        $this->write_log("分账");

        $this->write_log($fields);

        $this->write_log("分账结果");

        $this->write_log($result);

       return json_decode($result,true);



    }

     //查询带分账金额

    public function profitsharings($fields,$order_form='1'){



        $keyPath            =   $this->keyPath;

        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048';    //加密方式

        $url                =   "https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders/".$fields['transaction_id']."/amounts";    



        // $receivers          =   []; //分账接收方列表

        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息

        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号

        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书

        // foreach ($fields['receivers'] as $key => $value) {

        //     $arr            =   [

        //         // 'type'              =>  'MERCHANT_ID',          //分账接收方类型，枚举值：MERCHANT_ID：商户、PERSONAL_OPENID：个人

        //         'receiver_account'  =>  $value['mch_id'],       //分账接收方账号：商户号（mch_id或者sub_mch_id）、个人openid

        //         'amount'            =>  intval($value['amount']),       //分账金额，单位为分，只能为整数

        //         'description'       =>  $value['description'],  //分账的原因描述，分账账单中需要体现

        //     ];

        //     if(empty($value['type'])){

        //         $value['type'] = '1';

        //     }

        //     if($value['type']=='1'){

        //         $arr['type'] = 'MERCHANT_ID';

        //     }else{

        //         $arr['type'] = 'PERSONAL_OPENID';

        //         $arr['receiver_name'] = $this->getEncrypt($value['receiver_name'],$api_cert);

        //     }



        //     $receivers[]    = $arr;

        // }



        $data               =   [

            // 'appid'             =>  $this->appId,                   //公众号、小程序的 appid

            'sub_mchid'         =>  $fields['sub_mchid'],        //分账出资的电商平台二级商户，填写微信支付分配的商户号

            'transaction_id'    =>  $fields['transaction_id'],   //微信订单号

            // 'out_order_no'      =>  $fields['out_order_no'],     //商户分账单号

            // 'receivers'         =>  $receivers,                     //分账接收方列表

            // 'finish'            =>  false                            //是否分账完成

        ];

        if($order_form=='1'){

            $data['appid'] = $this->appId;

        }elseif($order_form=='3'){

            $data['appid'] = $this->appId2;

        }else{

            $data['appid'] = $this->appId1;

        }

        

        $filestr            =   json_encode($data);

        $time               =   time();

        $nonce_str          =   md5(time().mt_rand(0,1000));

        $pkid               =   file_get_contents($keyPath);



        $token              =   $this->get_sign($url,"GET",$time,$nonce_str,"",$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header             =   [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



       $result = PublicCurl($url,true,'GET',$filestr,$header);



       return json_decode($result,true);



    }

     //查询分账结果

    public function profitsharingss($fields,$order_form='1'){



        $keyPath            =   $this->keyPath;

        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048';    //加密方式

        $url                =   "https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders";    



        // $receivers          =   []; //分账接收方列表

        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息

        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号

        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书

       



        $data               =   [

            'sub_mchid'         =>  $fields['sub_mchid'],        //分账出资的电商平台二级商户，填写微信支付分配的商户号

            'transaction_id'    =>  $fields['transaction_id'],   //微信订单号

            'out_order_no'      =>  $fields['out_order_no'],     //商户分账单号

        ];

        $data['appid'] = $this->appId;

        $filestr            =   json_encode($data);

        $time               =   time();

        $nonce_str          =   md5(time().mt_rand(0,1000));

        $pkid               =   file_get_contents($keyPath);



        $token              =   $this->get_sign($url,"GET",$time,$nonce_str,"",$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header             =   [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        

       $result = PublicCurl($url,true,'GET',$filestr,$header);

        // dump($result);die;

       return json_decode($result,true);



    }

    /**

     * 分账回退

     * 

     * @param  Array    $fields          需要的字段

     *                  [

     *                      sub_mchid           分账出资的电商平台二级商户

     *                      out_order_no        商户系统内部的分账单号

     *                      out_return_no       此回退单号是商户在自己后台生成的一个新的回退单号，在商户后台唯一

     *                      return_mchid        只能对原分账请求中成功分给商户接收方进行回退

     *                      amount              需要从分账接收方回退的金额，单位为分，只能为整数

     *                      description         分账回退的原因描述

     *                  ]

     * 

     * @return String                       分账回退结果

     */

    public function returnorders($fields){



        $keyPath            =   $this->keyPath;

        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048';    //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/returnorders';



        $data               =   [

            'sub_mchid'             =>  $fields['sub_mchid'],        //分账出资的电商平台二级商户

            'out_order_no'          =>  $fields['out_order_no'],     //商户系统内部的分账单号

            'out_return_no'         =>  $fields['out_return_no'],    //此回退单号是商户在自己后台生成的一个新的回退单号，在商户后台唯一

            'return_mchid'          =>  $fields['return_mchid'],     //只能对原分账请求中成功分给商户接收方进行回退

            'amount'                =>  intval($fields['amount']),   //需要从分账接收方回退的金额，单位为分，只能为整数

            'description'           =>  '分账回退'                       //分账回退的原因描述

        ];



        $filestr            =   json_encode($data);

        $time               =   time();

        $nonce_str          =   md5(time().mt_rand(0,1000));

        $pkid               =   file_get_contents($keyPath);



        $token              =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header             =   [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);



    }



    /**

     * 完结分账（解冻资金回归支付商户）

     * 

     * @param  Array    $fields          需要的字段

     *                  [

     *                      sub_mchid           分账出资的电商平台二级商户

     *                      transaction_id      微信支付订单号

     *                      out_order_no        商户系统内部的分账单号，在商户系统内部唯一

     *                      description         分账的原因描述，分账账单中需要体现。

     *                  ]

     * 

     * @return String                       完结分账结果

     */

    public function finishOrder($fields){



        $keyPath            =   $this->keyPath;

        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048';    //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/finish-order';



        $data               =   [

            'sub_mchid'             =>  $fields['sub_mchid'],        //分账出资的电商平台二级商户

            'transaction_id'        =>  $fields['transaction_id'],   //微信支付订单号

            'out_order_no'          =>  $fields['out_order_no'],     //商户系统内部的分账单号，在商户系统内部唯一

            'description'           =>  '完结分账'                    //分账的原因描述，分账账单中需要体现。

        ];



        $filestr            =   json_encode($data);

        $time               =   time();

        $nonce_str          =   md5(time().mt_rand(0,1000));

        $pkid               =   file_get_contents($keyPath);



        $token              =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header             =   [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ",

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);



    }





    /**

     * 查询二级商户余额

     * @param  String   $sub_mchid    二级商户id

     * @return Array                    商户余额结果

     */

    public function get_shop_balance($sub_mchid = ''){

        

        if (empty($sub_mchid)) {

            throw new \RuntimeException('参数 $sub_mchid 不可为空');

        }



        $url            =   'https://api.mch.weixin.qq.com/v3/ecommerce/fund/balance/'.$sub_mchid;

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);



        return json_decode($result,true);

    }



    /**

     * 添加分账接收方

     * 

     * @param  Array    $fields          需要的字段

     *                  [

     *                      appid           微信分配的apppid（公众号APPID或者小程序APPID）

     *                      type            分账接收方的类型，枚举值：MERCHANT_ID：商户  PERSONAL_OPENID：个人

     *                      account         分账接收方的账号  类型是MERCHANT_ID时，是商户号  类型是PERSONAL_OPENID时，是个人openid

     *                      name            分账接收方的名称，当type为MERCHANT_ID时，接收方名称是商户全称

     *                      relation_type   子商户与接收方的关系。枚举值：SUPPLIER：供应商、DISTRIBUTOR：分销商、SERVICE_PROVIDER：服务商、PLATFORM：平台、OTHERS：其他

     *                  ]

     *        string    $type   分账接收方的类型（1：商户，2:个人）

     * 

     * @return String                       分账回退结果

     */

    public function receiversAdd($fields,$type='1',$order_form='1'){

      

        if($type=='1'){

            $type_name = 'MERCHANT_ID';

        }else{

            $type_name = 'PERSONAL_OPENID';

        }

        $keyPath            =   $this->keyPath;

        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048';    //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/receivers/add';



        $data               =   [

            // 'appid'             =>  $this->appId,       //微信分配的apppid（公众号APPID或者小程序APPID）

            'type'              =>  $type_name,      //分账接收方的类型，枚举值：MERCHANT_ID：商户  PERSONAL_OPENID：个人

            'account'           =>  $fields['account'], //分账接收方的账号  类型是MERCHANT_ID时，是商户号  类型是PERSONAL_OPENID时，是个人openid

            // 'name'              =>  $fields['name'],    //分账接收方的名称，当type为MERCHANT_ID时，接收方名称是商户全称

            'relation_type'     =>  'PLATFORM'          //与接收方关系枚举值:SUPPLIER:供应商、DISTRIBUTOR:分销商、SERVICE_PROVIDER:服务商、PLATFORM:平台、OTHERS:其他

        ];

        if(!empty($fields['name'])){

            $data['name'] =  $fields['name'];

        }

        if($order_form=='1'){

            $data['appid'] = $this->appId;

        }elseif($order_form=='3'){

            $data['appid'] = $this->appId2;

        }else{

            $data['appid'] = $this->appId1;

        }

        // var_dump($data);exit;

        $filestr            =   json_encode($data);

        $time               =   time();

        $nonce_str          =   md5(time().mt_rand(0,1000));

        $pkid               =   file_get_contents($keyPath);



        $token              =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header             =   [

            "Authorization: ".$schema.' '.$token,

            // "Wechatpay-Serial: ".$Wechatpay_Serial,//平台api证书序列号 添加直联商户时需要

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result = PublicCurl($url,true,'post',$filestr,$header);

        $this->write_log("添加");

        $this->write_log($fields);

        $this->write_log("分账方");

        $this->write_log($result);

        return json_decode($result,true);



    }



    /**

     * 删除分账接收方

     * 

     * @param  Array    $fields          需要的字段

     *                  [

     *                      appid           微信分配的apppid（公众号APPID或者小程序APPID）

     *                      type            分账接收方的类型，枚举值：MERCHANT_ID：商户  PERSONAL_OPENID：个人

     *                      account         分账接收方的账号  类型是MERCHANT_ID时，是商户号  类型是PERSONAL_OPENID时，是个人openid

     *                  ]

     * 

     * @return String                       分账回退结果

     */

    public function receiversDel($fields){



        $keyPath            =   $this->keyPath;

        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048';    //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/receivers/delete';



        $data               =   [

            'appid'             =>  $this->appId,       //微信分配的apppid（公众号APPID或者小程序APPID）

            'type'              =>  'MERCHANT_ID',      //分账接收方的类型，枚举值：MERCHANT_ID：商户  PERSONAL_OPENID：个人

            'account'           =>  $fields['account']  //分账接收方的账号  类型是MERCHANT_ID时，是商户号  类型是PERSONAL_OPENID时，是个人openid

        ];



        $filestr            =   json_encode($data);

        $time               =   time();

        $nonce_str          =   md5(time().mt_rand(0,1000));

        $pkid               =   file_get_contents($keyPath);



        $token              =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header             =   [

            "Authorization: ".$schema.' '.$token,

            // "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result = PublicCurl($url,true,'post',$filestr,$header);



        return json_decode($result,true);



    }



    /**

     * 修改结算帐号

     * 

     * @param  Array    $fields          需要的字段

     *                  [

     *                      sub_mchid           电商平台二级商户号，由微信支付生成并下发

     *                      account_type        ACCOUNT_TYPE_BUSINESS：对公银行账户、ACCOUNT_TYPE_PRIVATE：经营者个人银行卡

     *                      account_bank        开户银行

     *                      bank_address_code   开户银行省市编码

     *                      account_number      银行账号

     *                  ]

     * 

     * @return String                       分账回退结果

     */

    public function modifySettlement($fields){



        $keyPath            =   $this->keyPath;

        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048';    //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/'.$fields['sub_mchid'].'/modify-settlement';



        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书





        $data               =   [

            // 'sub_mchid'         =>  $fields['sub_mchid'], //电商平台二级商户号，由微信支付生成并下发

            'account_type'      =>  'ACCOUNT_TYPE_PRIVATE', //ACCOUNT_TYPE_BUSINESS：对公银行账户、ACCOUNT_TYPE_PRIVATE：经营者个人银行卡

            'account_bank'      =>  $fields['account_bank'], //开户银行

            'bank_address_code' =>  $fields['bank_address_code'], //开户银行省市编码

            'account_number'    =>  $this->getEncrypt($fields['account_number'],$api_cert) //银行账号

        ];



        $filestr            =   json_encode($data);

        $time               =   time();

        $nonce_str          =   md5(time().mt_rand(0,1000));

        $pkid               =   file_get_contents($keyPath);



        $token              =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result = PublicCurl($url,true,'post',$filestr,$header);

        return json_decode($result,true);



    }



    /**

     * 电商平台提现

     * 

     * @param  Array    $fields          需要的字段

     *                  [

     *                      sub_mchid       电商平台二级商户号，由微信支付生成并下发

     *                      out_request_no  商户提现单号，由商户自定义生成

     *                      amount          单位：分，金额不能超过8亿元

     *                  ]

     * 

     * @return String                       分账回退结果

     */

    public function takeCash($fields){



        $keyPath            =   $this->keyPath;

        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048';    //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/fund/withdraw';



        $data               =   [

            'sub_mchid'         =>  $fields['sub_mchid'],           //电商平台二级商户号，由微信支付生成并下发

            'out_request_no'    =>  $fields['out_request_no'],      //商户提现单号，由商户自定义生成

            'amount'            =>  intval($fields['amount'] * 100) //单位：分，金额不能超过8亿元

        ];

        

        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号

        $filestr            =   json_encode($data);

        $time               =   time();

        $nonce_str          =   md5(time().mt_rand(0,1000));

        $pkid               =   file_get_contents($keyPath);



        $token              =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header             =   [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result = PublicCurl($url,true,'post',$filestr,$header);



        return json_decode($result,true);



    }

    public function fentui($fields){



        $keyPath            =   $this->keyPath;

        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048';    //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/returnorders';



        $data               =   [

            'sub_mchid'         =>  $fields['sub_mchid'],           //电商平台二级商户号，由微信支付生成并下发

            'out_return_no'    =>  $fields['out_return_no'],      //商户提现单号，由商户自定义生成

            'amount'            =>  intval($fields['amount'] * 100), //单位：分，金额不能超过8亿元

            'order_id'  => $fields['order_id'],

            'return_mchid'=>$fields['return_mchid'],

            'description'=>"分账回退"

      

        ];

        

        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号

        $filestr            =   json_encode($data);

        $time               =   time();

        $nonce_str          =   md5(time().mt_rand(0,1000));

        $pkid               =   file_get_contents($keyPath);



        $token              =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header             =   [

            "Authorization: ".$schema.' '.$token,

            "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result = PublicCurl($url,true,'post',$filestr,$header);



        return json_decode($result,true);



    }

     



    /**

     * 微信支付提现单号查询

     * @param  String   $sub_mchid      二级商户id

     * @param  String   $withdraw_id    二级商户id

     * @return Array                    商户余额结果

     */

    public function getTakeCash($sub_mchid = '',$withdraw_id=''){

        

        if (empty($sub_mchid)) {

            throw new \RuntimeException('参数 $sub_mchid 不可为空');

        }



        if (empty($withdraw_id)) {

            throw new \RuntimeException('参数 $withdraw_id 不可为空');

        }



        $url            =   'https://api.mch.weixin.qq.com/v3/ecommerce/fund/withdraw/'.$withdraw_id.'?sub_mchid='.$sub_mchid;

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);



        return json_decode($result,true);

    }



    /**

     * 退款申请

     * 

     * @param  Array    $fields         退款订单信息

     *                  [

     *                      sub_mchid           二级商户号

     *                      out_trade_no        商户订单号

     *                      transaction_id      退款微信单号

     *                      out_refund_no       商户退款单号

     *                      refund              退款金额

     *                      total               原订单金额

     *                  ]                

     * 

     * @return Array                    退款订单信息

     */

    public function pay_refunds($fields){

        

        $error_array        =   [

            'sub_mchid'             =>  '二级商户号不可不空',

            'out_refund_no'         =>  '商户退款单号不可不空',

            'refund'                =>  '退款金额不可不空',

            'total'                 =>  '原订单金额不可不空'

        ];

        if(!isset($fields['out_trade_no'])){

            $fields['out_trade_no'] = '';   

        }

        // 'out_trade_no'          =>  '商户订单号不可不空',

        // 'transaction_id'        =>  '退款微信单号不可不空',

        if (empty($fields['out_trade_no']) && empty($fields['transaction_id'])) {

            throw new \RuntimeException('商户订单号、退款微信单号二选一');

        }

        //判断参数是否为空

        foreach ($error_array as $key => $value) {

            if (empty($fields[$key])) {

                throw new \RuntimeException($value);

            }

        }



        $keyPath            =   $this->keyPath;



        $merchant_id        =   $this->merchant_id;

        $serial_no          =   $this->serial_no;

        $schema             =   'WECHATPAY2-SHA256-RSA2048'; //加密方式



        $url                =   'https://api.mch.weixin.qq.com/v3/ecommerce/refunds/apply'; //二级商户进件注册地址



        $data               =   [



            'sub_mchid'             =>  $fields['sub_mchid'], //业务申请编号

            'sp_appid'              =>  $this->appId, //主体类型

            'out_refund_no'         =>  $fields['out_refund_no'], //主体类型

            'amount'                =>  [

                'refund'                    =>  intval($fields['refund']), //退款金额

                'total'                     =>  intval($fields['total']), //原订单金额

                'currency'                  =>  'CNY', //退款币种

            ], //主体类型

            'notify_url'            =>  "https://ximei.jituyangche.cn/Admin/Order_a/return_goods"

        ];



        if (!empty($fields['out_trade_no'])) {

            $data['out_trade_no']   =  $fields['out_trade_no']; //主体类型

        }else{

            $data['transaction_id'] =  $fields['transaction_id']; //主体类型

        }

        // var_dump($data);exit;

        $filestr    =   json_encode($data);

        // var_dump($filestr);exit;

        $time       =   time();

        $nonce_str  =   md5(time().mt_rand(0,1000));

        $pkid       =   file_get_contents($keyPath);



        $token      =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header  = [

            "Authorization: ".$schema.' '.$token,

            // "Wechatpay-Serial: ".$Wechatpay_Serial,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



       $result = PublicCurl($url,true,'post',$filestr,$header);



       return json_decode($result,true);

    }



    /**

     * 查询二级商户结算账户

     * @param  String   $sub_mchid      二级商户id

     * @return Array                    商户余额结果

     */

    public function get_shop_bank($sub_mchid = ''){

        

        if (empty($sub_mchid)) {

            throw new \RuntimeException('参数 $sub_mchid 不可为空');

        }



        $url            =   'https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/'.$sub_mchid.'/settlement';

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);



        return json_decode($result,true);

    }



    /**

     * 查询合并订单状态

     * @param  String   $ordernum       平台订单号

     * @return Array                    订单状态结果

     */

    public function get_heorder_state($ordernum = ''){

        

        if (empty($ordernum)) {

            throw new \RuntimeException('参数 $ordernum 不可为空');

        }



        $url            =   'https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/'.$ordernum;

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);



        return json_decode($result,true);

    }



    /**

     * [get_order_state description]

     * @param  string $ordernum     平台订单号

     * @param  string $sub_mchid    二级商户id

     * @return [type]               订单状态结果

     */

    public function get_order_state($ordernum = '',$sub_mchid = ''){

        

        if (empty($ordernum)) {

            throw new \RuntimeException('参数 $ordernum 不可为空');

        }



        if (empty($sub_mchid)) {

            throw new \RuntimeException('参数 $sub_mchid 不可为空');

        }



        // $url            =   'https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/'.$ordernum.'?sp_mchid='.$this->merchant_id.'&sub_mchid='.$sub_mchid;

        

        $url            =   'https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/'.$ordernum.'?sp_mchid='.$this->merchant_id.'&sub_mchid='.$sub_mchid;

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);



        return json_decode($result,true);

    }



    /**

     * 下载二级商户资金账单(sub_mchid)

     * @param  String   $date           查询日期

     * @param  String   $sub_mchid      二级商户号

     * @return Array                    商户进件状态结果

     */

    public function get_all_shop($date="2021-02-09",$sub_mchid = ''){

        

        if (empty($sub_mchid)) {

            $url        =   'https://api.mch.weixin.qq.com/v3/ecommerce/bill/fundflowbill?bill_date='.$date.'&account_type=ALL&tar_type=GZIP&algorithm=AEAD_AES_256_GCM';

        }else{

            $url        =   'https://api.mch.weixin.qq.com/v3/ecommerce/bill/fundflowbill?bill_date='.$date.'&account_type=ALL&tar_type=GZIP&algorithm=AEAD_AES_256_GCM';

        }

        

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);



        // $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        // $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号



        // $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        // $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        // $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        // $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书



        return json_decode($result,true);

    }



    public function down_file($url){



        if (empty($url)) {

            throw new \RuntimeException('参数 $url 不可为空');

        }



        // $url            =   'https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/'.$sub_mchid.'/settlement';

        $keyPath        =   $this->keyPath;



        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'get',$filestr,$header);

        // print_r($result);

        // return json_decode($result,true);

        return $result;

    }

     /**

     * 支付（特约商户小程序支付）

     * 使用费，维护费，保证金缴纳

     * @param  Array    $orderinfo          订单需要的字段

     *                  [

     *                      order_num       合并支付单号

     *                      openid          支付人openid

     *                      notify_url      回调地址

     *                      order_lists     子单列表

     *                          [

     *                              attach          附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。示例值：深圳分店

     *                              total_amount    订单总金额，单位为分

     *                              out_trade_no    商户系统内部订单号

     *                              sub_mchid       二级商户号

     *                              description     商品描述

     *                              profit_sharing  是否指定分账 true：是 false：否

     *                          ]

     *                  ]

     * 

     * @return String                       生成的支付信息

     */

    public function store_pay_new($orderinfo){

        $url            =   'https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi';

        // $keyPath        =   'E:/phpstudy_pro/WWW/energy-gathering-run/vendor/cert/apiclient_key.pem';

        // $keyPath        =   '/www/wwwroot/ceshi/vendor/cert/apiclient_key.pem';



        $merchant_id    =   $this->merchant_id;



        $data           =   [



            'sp_appid'              =>  $this->spappId,//$this->appId, //服务商公众号ID小程序ID wx1cce627c15ba0fc9

            'sp_mchid'              =>  $merchant_id, //服务商户号

            'sub_appid'             =>  $this->appId, //子商户应用ID

            'sub_mchid'             =>  $orderinfo['sub_mchid'], //子商户号

            'out_trade_no'          =>  $orderinfo['order_num'], //商户订单号

            'description'           =>  $orderinfo['description'], //商品描述

            'notify_url'            =>  $orderinfo['notify_url'], //通知地址
            'settle_info'                =>  [

                    'profit_sharing'             =>  $orderinfo['profit_sharing']

            ],
            'amount'                =>  [

                    'total'             =>  $orderinfo['total_amount']

            ],

            'payer'                 =>  [

                    'sp_openid'         =>  '',

                    'sub_openid'        =>  $orderinfo['openid']

            ]



        ];

        // dump($data);die;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   json_encode($data);

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($this->keyPath);



        $token          =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        // 设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];



        $result         =   PublicCurl($url,true,'post',$filestr,$header);
        $array=json_decode($result,1);
        if(isset($array['code']))
        {
            return $array;
        }
        // dump($array);die;

        $prepay_id      =   json_decode($result,1)['prepay_id'];

        

        if(empty($prepay_id)){

             throw new \RuntimeException('订单生成失败：'.json_decode($result,1)['message']);

        }



        $js_time        =   time();

        $js_str         =   md5(time().mt_rand(0,1000));



        $js_data        =   [



            'appId'         =>  $this->appId, //公众号、小程序名称

            'timeStamp'     =>  ''.$js_time, //时间戳

            'nonceStr'      =>  $js_str, //随机串

            'package'       =>  'prepay_id='.$prepay_id //公众号、小程序名称



        ];



        $token          =   $this->get_pay_sign($js_data,$pkid);



        $js_data['signType']    =   'RSA'; //微信签名方式

        $js_data['paySign']     =   $token; //微信签名

        

        return $js_data;

    }

     /**

     * 支付（特约商户小程序支付）

     * 保证金缴纳(业务员)

     * @param  Array    $orderinfo          订单需要的字段

     *                  [

     *                      order_num       合并支付单号

     *                      openid          支付人openid

     *                      notify_url      回调地址

     *                      order_lists     子单列表

     *                          [

     *                              attach          附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。示例值：深圳分店

     *                              total_amount    订单总金额，单位为分

     *                              out_trade_no    商户系统内部订单号

     *                              sub_mchid       二级商户号

     *                              description     商品描述

     *                              profit_sharing  是否指定分账 true：是 false：否

     *                          ]

     *                  ]

     * 

     * @return String                       生成的支付信息

     */

    public function user_pay_new($orderinfo){

        $url            =   'https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi';

        // $keyPath        =   'D:/phpstudy_pro/WWW/car_xcx/auto-parts-platform/vendor/certme/apiclient_key.pem';

        $keyPath        =   '/www/wwwroot/ceshi/vendor/cert/apiclient_key.pem';



        $merchant_id    =   '1607273729';



        $data           =   [



            'sp_appid'              =>  $this->appId,//$this->appId, //服务商公众号ID小程序ID wx1cce627c15ba0fc9

            'sp_mchid'              =>  $merchant_id, //服务商户号

            'sub_appid'             =>  $this->appId, //子商户应用ID

            'sub_mchid'             =>  '1608410402', //子商户号

            'out_trade_no'          =>  $orderinfo['he_order_num'], //商户订单号

            'description'           =>  $orderinfo['description'], //商品描述

            'notify_url'            =>  $orderinfo['notify_url'], //通知地址

            'amount'                =>  [

                    'total'             =>  $orderinfo['total_amount']

            ],

            'payer'                 =>  [

                    'sp_openid'         =>  '',

                    'sub_openid'        =>  $orderinfo['openid']

            ]



        ];

        // dump($data);die;

        $serial_no      =   '2F56C12F343280E0C34D7BBDE8EFCFDCE7CEAC44';

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   json_encode($data);

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"POST",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);

         // dump($token);die;

        // 设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        // dump($filestr);die;

        $result         =   PublicCurl($url,true,'post',$filestr,$header);

        dump($result);die;

        $prepay_id      =   json_decode($result,1)['prepay_id'];

        

        if(empty($prepay_id)){

             throw new \RuntimeException('订单生成失败：'.json_decode($result,1)['message']);

        }



        $js_time        =   time();

        $js_str         =   md5(time().mt_rand(0,1000));



        $js_data        =   [



            'appId'         =>  $this->appId, //公众号、小程序名称

            'timeStamp'     =>  ''.$js_time, //时间戳

            'nonceStr'      =>  $js_str, //随机串

            'package'       =>  'prepay_id='.$prepay_id //公众号、小程序名称



        ];



        $token          =   $this->get_pay_sign($js_data,$pkid);



        $js_data['signType']    =   'RSA'; //微信签名方式

        $js_data['paySign']     =   $token; //微信签名

        

        return $js_data;

    }

    

    /*查询支持个人业务的银行列表*/

    public function personal_banks($offset,$limit)

    {

        $url = 'https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/personal-banking?offset='.$offset.'&limit=' . $limit;

        $keyPath        =   $this->keyPath;

        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr        =   '';

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);



        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);



        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json"

        ];

        $result         =   PublicCurl($url,true,'get',$filestr,$header);

        return json_decode($result,true);

    }

    /*获取对私银行卡号开户银行*/

    public function search_bankcode_info($code)

    {

        $pingtai_list       =   $this->get_pingtai_list(); //获取平台证书信息



        $Wechatpay_Serial   =   $pingtai_list['data'][0]['serial_no']; //获取平台api证书序列号

        $associatedData     =   $pingtai_list['data'][0]['encrypt_certificate']['associated_data']; //"这是get_Certificate()获取到的associated_data";

        $nonceStr           =   $pingtai_list['data'][0]['encrypt_certificate']['nonce']; //"这是get_Certificate()获取到的noce";

        $ciphertext         =   $pingtai_list['data'][0]['encrypt_certificate']['ciphertext']; //"这是get_Certificate()获取到的ciphertext";

        $api_cert           =   $this->decryptToString($associatedData,$nonceStr,$ciphertext); //实时获取平台证书

        $code = $this->getEncrypt($code,$api_cert);

        $url = 'https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/search-banks-by-bank-account?account_number='.$code;

        $keyPath        =   $this->keyPath;

        $merchant_id    =   $this->merchant_id;

        $serial_no      =   $this->serial_no;

        $schema         =   'WECHATPAY2-SHA256-RSA2048';

        $filestr = '';

        // $filestr        =   [

        //     'account_number' => $code

        // ];

        // $filestr = '{account_number:'.$code.'}';

        // $filestr = json_encode($filestr,JSON_UNESCAPED_UNICODE);

        $time           =   time();

        $nonce_str      =   md5(time().mt_rand(0,1000));

        $pkid           =   file_get_contents($keyPath);

        $token          =   $this->get_sign($url,"GET",$time,$nonce_str,$filestr,$pkid,$merchant_id,$serial_no);

        #设置头部信息

        $header         =   [

            "Authorization: ".$schema.' '.$token,

            "User-Agent:111",

            "Accept:application/json",

            "Content-Type:application/json",

            "Wechatpay-Serial: ".$Wechatpay_Serial,

        ];

        $result         =   PublicCurl($url,true,'get',$filestr,$header);

        return json_decode($result,true);

    }

    function write_log($data){ 

        $url = './log/paylog/'.date('Ymd').'_log.txt';

        $dir_name=dirname($url);

          //目录不存在就创建

          if(!file_exists($dir_name))

          {

            //iconv防止中文名乱码

           $res = mkdir(iconv("UTF-8", "GBK", $dir_name),0777,true);

          }

          $fp = fopen($url,"a");//打开文件资源通道 不存在则自动创建       

        fwrite($fp,var_export($data,true)."\r\n");//写入文件

        fclose($fp);//关闭资源通道

    }

}